package cn.iocoder.yudao.module.shop.service.jiucase;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.shop.dal.dataobject.order.ShopOrderDO;
import cn.iocoder.yudao.module.shop.dal.dataobject.orderfeedback.ShopOrderFeedbackDO;
import cn.iocoder.yudao.module.shop.dal.mysql.order.ShopOrderMapper;
import cn.iocoder.yudao.module.shop.service.masterstatistics.ShopMasterStatisticsService;
import cn.iocoder.yudao.module.shop.service.order.ShopOrderService;
import cn.iocoder.yudao.module.shop.service.orderfeedback.ShopOrderFeedbackService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenantdetail.TenantDetailDO;
import cn.iocoder.yudao.module.system.service.tenantdetail.TenantDetailService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.time.Period;

import java.util.*;
import cn.iocoder.yudao.module.shop.controller.admin.jiucase.vo.*;
import cn.iocoder.yudao.module.shop.dal.dataobject.jiucase.ShopJiuCaseDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.shop.convert.jiucase.ShopJiuCaseConvert;
import cn.iocoder.yudao.module.shop.dal.mysql.jiucase.ShopJiuCaseMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.shop.enums.ErrorCodeConstants.*;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;

/**
 * 店铺灸法案例 Service 实现类
 *
 * @author 曹建伟
 */
@Service
@Validated
public class ShopJiuCaseServiceImpl implements ShopJiuCaseService {

    @Resource
    private ShopJiuCaseMapper jiuCaseMapper;


    @Resource
    private ShopOrderFeedbackService shopOrderFeedbackService;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private AdminUserApi adminUserApi;

    @Resource
    private TenantDetailService tenantDetailService;

    @Resource
    private ShopOrderService shopOrderService;

    @Resource
    private ShopOrderMapper shopOrderMapper;

    @Resource
    private MemberUserService memberUserService;

    @Resource
    private ShopMasterStatisticsService shopMasterStatisticsService;


    @Override
    public Long createJiuCase(ShopJiuCaseCreateReqVO createReqVO) {
        // 插入
        ShopJiuCaseDO jiuCase = ShopJiuCaseConvert.INSTANCE.convert(createReqVO);
        jiuCaseMapper.insert(jiuCase);
        // 返回
        return jiuCase.getId();
    }

    @Override
    public void updateJiuCase(ShopJiuCaseUpdateReqVO updateReqVO) {
        // 校验存在
        validateJiuCaseExists(updateReqVO.getId());
        // 更新
        ShopJiuCaseDO updateObj = ShopJiuCaseConvert.INSTANCE.convert(updateReqVO);
        jiuCaseMapper.updateById(updateObj);
    }

    @Override
    public void deleteJiuCase(Long id) {
        // 校验存在
        validateJiuCaseExists(id);
        // 删除
        jiuCaseMapper.deleteById(id);
    }

    private void validateJiuCaseExists(Long id) {
        if (jiuCaseMapper.selectById(id) == null) {
            throw exception(JIU_CASE_NOT_EXISTS);
        }
    }

    @Override
    public ShopJiuCaseDO getJiuCase(Long id) {
        return jiuCaseMapper.selectById(id);
    }

    @Override
    public List<ShopJiuCaseDO> getJiuCaseList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return jiuCaseMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ShopJiuCaseDO> getJiuCasePage(ShopJiuCasePageReqVO pageReqVO) {
        return jiuCaseMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ShopJiuCaseDO> getJiuCaseList(ShopJiuCaseExportReqVO exportReqVO) {
        return jiuCaseMapper.selectList(exportReqVO);
    }

    @Override
    public List<ShopJiuCaseFullRespVO> getMemberJiucaseList(Long memberId){

        List<ShopJiuCaseDO> caseList = jiuCaseMapper.selectList(new LambdaQueryWrapperX<ShopJiuCaseDO>()
                .eq(ShopJiuCaseDO::getMemberId, memberId));

        List<Long> orderIds = CollectionUtils.convertList(caseList, ShopJiuCaseDO::getOrderId);
        List<ShopOrderFeedbackDO> feedbackList = shopOrderFeedbackService.getListbyOrderId(orderIds);

        Map<Long, ShopOrderFeedbackDO> feedbackMap = CollectionUtils.convertMap(feedbackList, ShopOrderFeedbackDO::getOrderId);

        List<ShopJiuCaseFullRespVO> list = new ArrayList<>();
        for(int i = 0; i<caseList.size(); i++){
            ShopJiuCaseFullRespVO respVO = new ShopJiuCaseFullRespVO();
            respVO.setJiucase(caseList.get(i));
            respVO.setFeedback(feedbackMap.get(caseList.get(i).getOrderId()));

            list.add(respVO);
        }

        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createShopJiuCase(ShopJiuCaseOrderCreateReqVO createReqVO){
        Long orderId = createReqVO.getOrderId();
        String title = createReqVO.getTitle();
        String tags = createReqVO.getTags();
        String content = createReqVO.getContent();
        String pic = createReqVO.getPic();
        String video = createReqVO.getVideo();

        ShopOrderDO order = shopOrderMapper.selectById(orderId);
        if(order == null){
            throw exception(JIU_CASE_CREATE_ERROR_ORDER);
        }

        Long memberId = order.getMemberId();
        Long masterId = order.getUserId();
        Long tenantId = order.getTenantId();

        MemberUserDO member = memberUserService.getUser(memberId);
        if(member == null){
            throw exception(JIU_CASE_CREATE_ERROR_MEMBER);
        }

        AdminUserRespDTO user = adminUserApi.getUser(masterId);
        if(user == null){
            throw exception(JIU_CASE_CREATE_ERROR_MASTER);
        }

        TenantDetailDO tenant = tenantDetailService.getTenantDetailByTenantId(tenantId);
        if(tenant == null) {
            throw exception(JIU_CASE_CREATE_ERROR_TENANT);
        }

        Long count = jiuCaseMapper.selectCount(ShopJiuCaseDO::getMemberId, memberId);

        ShopJiuCaseDO jiuCaseDO = new ShopJiuCaseDO();
        jiuCaseDO.setOrderId(orderId);
        jiuCaseDO.setTimes(count.intValue() + 1);

        jiuCaseDO.setMemberId(memberId);
        LocalDateTime birtyday = member.getBirthday();
        if(birtyday != null){
            LocalDateTime now = LocalDateTime.now();
            jiuCaseDO.setMemberAge(Period.between(birtyday.toLocalDate(), now.toLocalDate()).getYears());
        }else{
            jiuCaseDO.setMemberAge(0);
        }

        jiuCaseDO.setMemberName(member.getNickname());
        jiuCaseDO.setMemberPhone(member.getMobile());
        jiuCaseDO.setMemberSex(member.getSex().byteValue());
        jiuCaseDO.setMemberWeight(0);

        jiuCaseDO.setUserId(masterId);
        jiuCaseDO.setUserName(user.getNickname());

        jiuCaseDO.setTenantName(tenant.getName());
        jiuCaseDO.setTenantId(tenantId);

        jiuCaseDO.setTitle(title);
        jiuCaseDO.setTags(tags);
        jiuCaseDO.setContent(content);
        jiuCaseDO.setCommentNum(0);
        jiuCaseDO.setLikeNum(0);
        jiuCaseDO.setReadNum(0);
        jiuCaseDO.setKeyword(title + tags);
        jiuCaseDO.setLevelId(-1L);
        jiuCaseDO.setPicUrl(pic);
        jiuCaseDO.setVideoUrl(video);

        jiuCaseDO.setShowType(0);

        jiuCaseMapper.insert(jiuCaseDO);

        order.setHistoryId(jiuCaseDO.getId());
        shopOrderMapper.updateById(order);

        shopMasterStatisticsService.recordJiucase(jiuCaseDO);

        return jiuCaseDO.getId();

    }

}
